#include "interface.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

/* 函数功能：弹出一个新界面
 * 入口参数：GladeXML **window
 *         界面对应的窗口
 *         char *str
 *         新界面对应的glade窗口名称
 *         guint treeType
 *         0，无树；1，有树
 * 出口参数：无
 * 返 回 值 ：int
 *         SUCCESS  函数成功执行
 *         FAILURE  函数执行出错
 * 创建日期：2009年7月8号
 * 创 建 人 ：匡波 马小艳
 * 更新历史：暂无
 */
gint call(GladeXML **window, gint argc, gchar **argv, gchar *str, gint treeType)
{
   gtk_init(&argc, &argv);

   *window = glade_xml_new(str ,NULL, NULL);
   glade_xml_signal_autoconnect( *window );

   switch ( treeType )
   {
        /* 本地虚拟机镜像 */
        case LOCAL_IMAGE_LIST:
             
             treeView(*window, "SdVmTree", LOCAL_IMAGE_LIST);
             break;

        /* 本地隐私数据 */
        case LOCAL_SECRET_DATA_TREE:

             treeView(*window, "SdLocalTree", LOCAL_SECRET_DATA_TREE);
             /* break; */
             /* 同时显示两个棵树，不执行break,接着执行 */
 
	    /* 服务器隐私数据 */
        case SERVER_SECRET_DATA_TREE:

             treeView(*window, "SdServerTree", SERVER_SECRET_DATA_TREE);
             break;
      
        default:
 
             break;
   }

#ifdef DEBUG
   g_print("%s: %d :call window %x\n", __FILE__, __LINE__, *window);
#endif

     /* 设置弹出窗口为独占模式 */
    GtkWidget *win = NULL;
    win = glade_xml_get_widget(*window, "window1");
    gtk_window_set_modal ( GTK_WINDOW( win ), TRUE);   

    gtk_main();
  
    return SUCCESS;
}

/* 函数功能：弹出一个提示对话框
 * 入口参数：GtkButtonsType buttons
 *         对话框显示的按钮类型
 *         const gchar *message_format
 *         对话框显示的消息内容和格式
 * 出口参数：无
 * 返 回 值 ：gint
 *         result 被点击按钮的返回值
 * 创建日期：2009年7月8号
 * 创 建 人 ：匡波 马小艳
 * 更新历史：暂无
 */
gint showDialog(GtkWindow *parent,
                GtkDialogFlags flags,
	            GtkMessageType type,
                GtkButtonsType buttons,
                const gchar *message_format,
                ...)
{
   gint result = 0;
   va_list arg_ptr;
   va_start(arg_ptr, message_format);

   GtkWidget *dialog = NULL;
   /* 生成对话框 */
   dialog = gtk_message_dialog_new (parent,
                                    flags,
                                    type,
                                    buttons,
                                    message_format,
                                    arg_ptr);
   va_end(arg_ptr);

   /* 显示对话框,获取返回结果 */
   result = gtk_dialog_run ( GTK_DIALOG (dialog) );
   
   gtk_widget_destroy (dialog);
   
   return result;
}

/* 函数功能：弹出一个提示对话框***************************************************
 * 入口参数：GtkButtonsType buttons
 *         对话框显示的按钮类型
 *         const gchar *message_format
 *         对话框显示的消息内容和格式
 * 出口参数：无
 * 返 回 值 ：gint
 *         result 被点击按钮的返回值
 * 创建日期：2009年7月8号
 * 创 建 人 ：匡波 马小艳
 * 更新历史：暂无
 */
gint addListColum(GtkTreeView * treeview, char* title, char * type, int index)
{
   GtkCellRenderer *renderer;
   GtkTreeViewColumn *column;
   
   /* 设置list列的属性：标题、类型 */
   if( !strcmp (type, "text") )
   {
       /* 列属性为字符串 */
       renderer = gtk_cell_renderer_text_new ();
       column = gtk_tree_view_column_new_with_attributes (title,
						          renderer,
		                                          type,
						          index,
				                          NULL);
   }
   else if ( !strcmp (type, "pixbuf") )
   {
       /* 列属性为图标 */
       renderer = gtk_cell_renderer_pixbuf_new ();
       column = gtk_tree_view_column_new_with_attributes (title,
						          renderer,
						          type,
						          index,
						          NULL);
   }
   /* 设置列可拖动 */
   gtk_tree_view_column_set_resizable(column, TRUE);
   
   /* 将该列添加到listview中 */
   gtk_tree_view_append_column (treeview, column);

   return SUCCESS;
}

/* 函数功能：弹出一个提示对话框***************************************************
 * 入口参数：GtkButtonsType buttons
 *         对话框显示的按钮类型
 *         const gchar *message_format
 *         对话框显示的消息内容和格式
 * 出口参数：无
 * 返 回 值 ：gint
 *         result 被点击按钮的返回值
 * 创建日期：2009年7月8号
 * 创 建 人 ：匡波 马小艳
 * 更新历史：暂无
 */
gint addListRow(GtkWidget * treeview, void **ListStore, guint Type)
{
   GtkTreeModel *model;

   switch ( Type )
   {
        /* 本地虚拟机镜像 */
        case LOCAL_IMAGE_LIST:
   
             *ListStore = gtk_list_store_new(NUM_IMAGE_COLS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
             break;

        /* 本地隐私数据 */
        case LOCAL_SECRET_DATA_TREE:

             *ListStore = gtk_tree_store_new(NUM_FILE_COLS, GDK_TYPE_PIXBUF, G_TYPE_STRING);
             break;
        
        /* 服务器隐私数据 */
        case SERVER_SECRET_DATA_TREE:

             *ListStore = gtk_tree_store_new(NUM_FILE_COLS, GDK_TYPE_PIXBUF, G_TYPE_STRING);
             break;
       
        default:
 
             break;

   }
   
   /* 设置listview模式 */
   model = GTK_TREE_MODEL( *ListStore );
   gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), model);
   
   /* 将随主窗口销毁而释放内存 */
   g_object_unref (model);
   
   return SUCCESS;
}

/* 函数功能：创建一棵树
 * 入口参数：GladeXML *Window
 *         界面对应的窗口
 *         gchar *TreeView
 *         树的名字
 *         guint Type
 *         树对应的类型
 * 出口参数：无
 * 返 回 值 ：int
 *         SUCCESS  函数成功执行
 *         FAILURE  函数执行出错
 * 创建日期：2009年7月8号
 * 创 建 人 ：匡波 马小艳
 * 更新历史：暂无
 */
gint treeView(GladeXML *Window, gchar *TreeView, guint Type)
{

   GtkWidget * treeview = NULL;

   GtkTreeModel *model = NULL;
   GtkListStore *liststore = NULL;
   GtkTreeStore *treestore = NULL;
   GtkTreeIter iter;

   /* 图标单元指针 */
   GdkPixbuf *pixbuf = NULL;

   gint i = 0;

   /* 隐私文件路径 */
   gchar dir[MAXPATH];

   /* 文件路径初始化，设置初值，interface.h：SD_PATH */
   memset(dir, sizeof(dir), 0);
   strcpy(dir, SD_PATH);

   /* 获取窗口的treeview控件指针 */
   treeview = glade_xml_get_widget(Window, TreeView);

   /* 获取树控件失败 */
   if(treeview == NULL)
   {
    
     g_print("%s Line %d: Get widget error!, Treeview is null \n ", __FILE__, __LINE__);

     return FAILURE;

   }
  
   /* 获取treeview 模式 */
   model = gtk_tree_view_get_model ( GTK_TREE_VIEW(treeview ) );
   liststore = GTK_LIST_STORE( model );

   switch ( Type )
   {
        /* 本地虚拟机镜像 */
        case LOCAL_IMAGE_LIST:   
             {
                   /* 列标题名称 */
                   gchar *Title[] = {"镜像名称           ", "下载日期            ", "一次登录日期            "};          

                   /* 设置列表的列信息 */
                   for(i = 0; i < NUM_IMAGE_COLS; i++)
  	                   addListColum(GTK_TREE_VIEW( treeview ), Title[i], "text",  i);
   
                   /* 设置列表的行信息 */
                   addListRow(treeview, (void **)&liststore, Type);

                   /* 添加一行信息到listview中 */
                   gchar *Row1[] = {"WhuIsInstitute.img", "2009年7月7日", "2009年8月8日 8：8"};
   
                   gtk_list_store_append(liststore, &iter);
  
                   for(i = 0; i< NUM_IMAGE_COLS ; i++)
   	                 gtk_list_store_set (liststore, 
		      	                         &iter,
   			                             i,    
                                         Row1[i],
  			                             -1 );
                   /* TODO 添加行 */ 

             }while(0);      

             break;

        /* 本地隐私数据 */
        case LOCAL_SECRET_DATA_TREE:
        {
             /* 列标题名 */
             gchar *Title[] = {"Icon          ", "FileName            "};          

             /* 设置列表的列信息 */
  	         addListColum(GTK_TREE_VIEW( treeview ), Title[0], "pixbuf",  0);
  	         addListColum(GTK_TREE_VIEW( treeview ), Title[1], "text",  1);
   
             /* 设置列表的行信息 */
             addListRow(treeview, (void **)&treestore, Type);

             /* 添加一行信息到listview中，为树的第一层 */
             gtk_tree_store_append(treestore, &iter, NULL);
  
             for(i = 0; i< NUM_FILE_COLS ; i++)
             {
   	             if (i == 0)
                 {
                     /* 第一列为图标 */
                     pixbuf = gdk_pixbuf_new_from_file("doc.png", NULL);
                     gtk_tree_store_set (treestore, 
		      	                         &iter,
   			                             i, 
                                         pixbuf,
  		 	                             -1 );
                  }
                  else if(i == 1)
                  {
                       /* 第二列为文件名字符串 */
                       gtk_tree_store_set (treestore, 
		      	                           &iter,
   			                               i, 
                                           SD_PATH,
  		 	                               -1 );
                  }
              }
                   
                  /* 遍历当前目录及所有子目录，作为子节点 */ 
                  getfile( dir, treestore, iter);

             }while(0);
                  break;
       
        /* 服务器隐私数据 */
        case SERVER_SECRET_DATA_TREE:
        {
            /* 列标题名 */
            gchar *Title[] = {"Icon           ", "FileName              "};
            
            /* 设置列表的列信息 */
            addListColum(GTK_TREE_VIEW( treeview ), Title[0], "pixbuf",  0);
  	        addListColum(GTK_TREE_VIEW( treeview ), Title[1], "text",  1);
  
            /* 设置列表的行信息 */
            addListRow(treeview, (void **)&treestore, Type);

            /* 添加一行信息到listview中 */  
            gtk_tree_store_append(treestore, &iter, NULL);
  
            for(i = 0; i< NUM_FILE_COLS ; i++)
   	        {
   	            if(i == 0)
                {
                   /* 第一列为图标 */
                   pixbuf = gdk_pixbuf_new_from_file("lock.png", NULL);
                   gtk_tree_store_set (treestore, 
		      	                       &iter,
   			                           i, 
                                       pixbuf,
  		 	                           -1 );
                }
                else if(i == 1)
                {
                    /* 第二列为文件名字符串 */
                    gtk_tree_store_set (treestore, 
		      	                        &iter,
   			                            i, 
                                        SD_PATH,
  		 	                            -1 );
                }
            }

            /* 遍历当前目录及所有子目录，作为子节点 */  
            getfile( dir, treestore, iter);

      }while(0);
           break;

      default:
           break;
   }
   
   return SUCCESS;
}

/* 函数功能：根据dir目录创建一棵树，显示该目录下的所有文件
 * 入口参数：char *dir
 *         当前的目录
 *         GtkTreeStore *treestore
 *         树控件指针，
 *         GtkTreeIter iter
 *         该目录作为子树的父节点，的节点指针
 * 出口参数：无
 * 返 回 值 ：int
 *         SUCCESS  函数成功执行
 *         FAILURE  函数执行出错
 * 创建日期：2009年7月8号
 * 创 建 人 ：匡波 马小艳
 * 更新历史：暂无
 */
int getfile(char *dir , GtkTreeStore *treestore, GtkTreeIter iter)
{
    GtkTreeIter child;
    GdkPixbuf *pixbuf = NULL;
    GtkWidget *cellView = NULL;
    gint i = 0, j = 0;
	
    /* 定位文件名字位置 */
    gchar *pc = NULL;
	
    /* 将dir拼接子文件夹，作为新文件夹根路径 */
    gchar dirchild[MAXPATH] ;

	/* buf 存储ls 命令的每一行内容 */
    gchar buf[MAXPATH];
        
    /* 保存popen 执行的shell 命令 */
    gchar cmd[MAXPATH];
        
    /* 管道文件指针 */
	FILE *pp = NULL;    
 
    /* 设置数组初值 */
    memset(buf, sizeof(buf), 0);
    memset(cmd, sizeof(cmd), 0);
        
    /* 命令前半部分 */
    strcpy( cmd , "ls -lpB ");

    /* 命令中要打开的文件夹路径*/
    if ( !strcat( cmd, dir ))
	{
		/* g_print("%s:%s:strcat error\n", __FILE__, __LINE__); */
	}

        /* g_print("cmd = %s, dir =%s ", cmd, dir); */
        /* 打开管道 */
        if((pp = popen(cmd , "r")) == NULL )
        {
		    g_print("%s : %d:popen() error!\n", __FILE__, __LINE__); 
		   
		    return FAILURE;
        }
          
         /* 读取第一行，属性无用行 */
         fgets(buf, sizeof(buf), pp);
         
         /* 循环读取文件内容到buf，每次一行 */
         while(fgets(buf, sizeof(buf), pp))
         {
             /* 找到时间分割符，时间后面为空格和文件名 */
		     pc = strchr(buf, ':');
		     if(!pc)
		     {
			     /* 不存在时间分隔符，出错 */
                g_print("%s:%d:No match letter ：\n", __FILE__, __LINE__);
			 
		 	    return FAILURE;
		     }
		     else	
		     {
			    /* 查找时间和文件名的分割符：空格 */
			    pc = strchr(pc, ' ');
			 }

		     if(*buf == 'd')
		     {
			    /* 该文件为文件夹，加入当前层，将该文件夹作为根，文件夹作为其字节点 */

			    /* 初始化要遍历的子文件夹:当前文件夹/自文件夹名 */
			    memset(dirchild, sizeof(dirchild), 0);
			    strcpy( dirchild, dir);	
	
			    /*用'\ '替换' '字符，sh命令将用'\ '替换' ' */
                            j = strlen( dirchild );
                            for (i = 0; i<= strlen (pc + 1); i++)
                            {
                                 if (*(pc + 1 + i) == ' ')
                                 {
                                      *(dirchild + j) = '\\';
                                      j++;

                                 }

                                 *(dirchild + j) = *(pc + 1 +i);
                                 j++; 
                            }
                            g_print( "dirchild = %s", dirchild );
			    /* 设置文件图标为文件夹 */
			    cellView = gtk_cell_view_new();
                pixbuf = gtk_widget_render_icon(cellView, GTK_STOCK_DIRECTORY,
	            GTK_ICON_SIZE_BUTTON, NULL);

			    /* 将图标和文件名添加到当前层*/
                gtk_tree_store_append(treestore, &child, &iter);
                gtk_tree_store_set(treestore, 
                                   &child, 
                                   ICON_NAME, 
                                   pixbuf,
                                   FILE_NAME, 
                                   pc + 1,
                                   -1);
                gdk_pixbuf_unref(pixbuf);
			
			    /* 遍历该子目录文件 */
                getfile( dirchild , treestore, child);
		   }
		   else if(*buf == '-')
		   {
			    /* 该文件为普通文件，直接加入当前层 */
		
			    /* 设置文件图标为文件 */
			    cellView = gtk_cell_view_new();
                pixbuf = gtk_widget_render_icon(cellView,
                                                GTK_STOCK_FILE,
	                 			                GTK_ICON_SIZE_BUTTON,
	                 			                NULL);

			    /* 将文件图标和文件名添加到当前层 */
                gtk_tree_store_append(treestore, &child, &iter);
                gtk_tree_store_set(treestore, 
                                   &child, 
                                   ICON_NAME, 
                                   pixbuf,
                                   FILE_NAME, 
                                   pc + 1,
                                   -1);
                gdk_pixbuf_unref(pixbuf);
		   }
       }/* end while */

	   /* 关闭文件 */
       pclose(pp);

       return SUCCESS;
}

/* 函数功能：进度条进度显示函数
 * 入口参数：gpointer data
 *         进度条空件指针：data->pb
                      进度条每次增加的值：data->step
 * 出口参数：无
 * 返 回 值 ：int
 *         SUCCESS  函数成功执行
 *         FAILURE  函数执行出错
 * 创建日期：2009年7月8号
 * 创 建 人 ：匡波 马小艳
 * 更新历史：暂无
 */
gint progress_timeout(gpointer data)
{
	gdouble new_val;
	
	if(data == NULL)
	    return FALSE;
  
    /*获取PROGRESSBAR结构体指针*/ 
    PROGRESSBAR *pbar = (PROGRESSBAR *)data;
    
    /*获取进度条当前的进度值*/
    new_val = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (pbar->pb)) + pbar->step;
    
    /*如果值大于1.0则进度条已经完成*/  
    if (new_val >= 1.0)
    {
            /*设置进度条为可用*/
            flag = 0;

            /*并把进度条初值设为0*/
            gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pbar->pb), 0.0);

	    return FALSE;
    }
    
    /*设置进度条的新值*/
    gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pbar->pb), new_val);
      
    /* 这是一个timeout函数，返回 TRUE，这样它就能够继续被调用 */
    return TRUE;
} 
